﻿using System;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web.UI;
using Ext.Net;
using Ext.Net.UIS;
using KamLib;
using KamLib.Converts;

//using Newtonsoft.Json;


namespace Ext.Net
{
    public static class ExtUtils
    {

        #region StateBag

        public static T Try<T>(this StateBag state, string name)
        {
            var obj = state[name];
            return obj is T ? (T)obj : default(T);
        }

        public static T Try<T>(this StateBag state, string name, T defaultValue)
        {
            var obj = state[name];
            return obj is T ? (T)obj : defaultValue;
        }

        //public static T Try<T>(this ViewStateProxy state, string name)
        //{
        //    var obj = state[name];
        //    return obj is T ? (T)obj : default(T);
        //}

        //public static T Try<T>(this ViewStateProxy state, string name, T defaultValue)
        //{
        //    var obj = state[name];
        //    return obj is T ? (T)obj : defaultValue;
        //}

        #endregion


        #region Store

        //public static void AddFields(this Store store, Type modelType)
        //{
        //    var rdr = store.Reader.FirstOrDefault();
        //    if (rdr == null) return;

        //    rdr.Fields.Clear();
        //    foreach (var p in modelType.GetPropertiesAndFields().Where(p => p.GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Length == 0))
        //    {
        //        store.AddField(new RecordField(p.Name, TypeToFieldType(p)));
        //    }
        //}

        //public static void AddFields(this DataReader rdr, Type type)
        //{
        //    rdr.Fields.Clear();
        //    rdr.Fields.AddRange(
        //        type.GetPropertiesAndFields()
        //        .Where(p => p.GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Length == 0)
        //        .Select(p => new RecordField(p.Name, TypeToFieldType(p), "M$")
        //        {
        //            UseNull = p.ResultType().Name.StartsWith("Nullable")
        //        })
        //    );
        //}

        //public static void AddFields(this DataReader rdr, DbDataReader r)
        //{
        //    rdr.Fields.Clear();
        //    for (var i = 0; i < r.FieldCount; ++i)
        //    {
        //        rdr.Fields.Add(
        //            new RecordField(r.GetName(i), TypeToFieldType(r.GetFieldType(i))) { DateFormat = "M$" }
        //        );
        //    }
        //}


        //public static RecordFieldType TypeToFieldType(MemberInfo member)
        //{
        //    var propertyInfo = member as PropertyInfo;
        //    if (propertyInfo != null)
        //        return TypeToFieldType((propertyInfo).PropertyType);

        //    var fieldInfo = member as FieldInfo;
        //    if (fieldInfo != null)
        //        return TypeToFieldType((fieldInfo).FieldType);

        //    return RecordFieldType.Auto;
        //}


        //public static RecordFieldType TypeToFieldType(Type ptype)
        //{
        //    if (ptype == typeof(DateTime) || ptype == typeof(DateTime?))
        //    {
        //        return RecordFieldType.Date;
        //    }
        //    if (ptype == typeof(int) || ptype == typeof(int?))
        //    {
        //        return RecordFieldType.Int;
        //    }
        //    if (ptype == typeof(double) || ptype == typeof(double?) ||
        //        ptype == typeof(decimal) || ptype == typeof(decimal?) ||
        //        ptype == typeof(float) || ptype == typeof(float?))
        //    {
        //        return RecordFieldType.Float;
        //    }
        //    if (ptype == typeof(bool) || ptype == typeof(bool?))
        //    {
        //        return RecordFieldType.Boolean;
        //    }
        //    return RecordFieldType.Auto;
        //}

        //public static Column NewColumn(Type ptype)
        //{
        //    if (ptype == typeof(DateTime) || ptype == typeof(DateTime?))
        //    {
        //        return new DateTimeColumn();
        //    }
        //    if (ptype == typeof(int) || ptype == typeof(int?))
        //    {
        //        return new IntColumn();
        //    }
        //    if (ptype == typeof(double) || ptype == typeof(double?) ||
        //        ptype == typeof(decimal) || ptype == typeof(decimal?) ||
        //        ptype == typeof(float) || ptype == typeof(float?))
        //    {
        //        return new FloatColumn();
        //    }
        //    if (ptype == typeof(bool) || ptype == typeof(bool?))
        //    {
        //        return new YesNoColumn();
        //    }
        //    return new Column();
        //}


        //public static object ValueAsObject(this FilterCondition condition)
        //{
        //    switch (condition.FilterType)
        //    {
        //        case FilterType.Boolean:
        //            return condition.ValueAsBoolean;
        //        case FilterType.Date:
        //            return condition.ValueAsDate;
        //        case FilterType.List:
        //            return condition.ValuesList;
        //        case FilterType.Numeric:
        //            return condition.ValueAsDouble;
        //        case FilterType.String:
        //            return condition.Value;
        //        default:
        //            throw new ArgumentOutOfRangeException();
        //    }
        //}

        //public static string SqlCondition(this GridFilters gridFilters, StoreRefreshDataEventArgs e)
        //{
        //    var sfilter = e.Parameters[gridFilters.ParamPrefix];
        //    return sfilter.isnull() ? null : SqlCondition(new FilterConditions(sfilter));
        //}

        //public static string SqlCondition(FilterConditions fc)
        //{
        //    var sb = new StringBuilder();

        //    foreach (var condition in fc.Conditions)
        //    {
        //        var value = condition.ValueAsObject();

        //        if (sb.Length > 0) sb.Append(" and ");
        //        sb.Append(condition.Name);
        //        switch (condition.Comparison)
        //        {
        //            case Comparison.Eq:
        //                switch (condition.FilterType)
        //                {
        //                    case FilterType.List:
        //                        sb.Append(" in (");
        //                        foreach (var lvalue in (ReadOnlyCollection<string>)value)
        //                        {
        //                            sb.Append(SystemDataHelper.ToParam(lvalue));
        //                            sb.Append(", ");
        //                        }
        //                        sb.AppendLine(")");
        //                        break;
        //                    case FilterType.String:
        //                        sb.Append(" like ");
        //                        sb.Append(SystemDataHelper.ToParam(value + "%"));
        //                        break;
        //                    default:
        //                        sb.Append(" = ");
        //                        sb.Append(SystemDataHelper.ToParam(value));
        //                        break;
        //                }
        //                break;
        //            case Comparison.Gt:
        //                sb.Append(" >= ");
        //                sb.Append(SystemDataHelper.ToParam(value));
        //                break;
        //            case Comparison.Lt:
        //                sb.Append(" =< ");
        //                sb.Append(SystemDataHelper.ToParam(value));
        //                break;
        //            default:
        //                throw new ArgumentOutOfRangeException();
        //        }
        //    }
        //    return sb.ToString();
        //}

        #endregion


        #region Parameters

        public static ParameterCollection AddValue(this ParameterCollection a, string name, string value)
        {
            a.Add(new Parameter { Name = name, Value = value, Mode = ParameterMode.Value });
            return a;
        }
        public static ParameterCollection AddRaw(this ParameterCollection a, string name, string value)
        {
            a.Add(new Parameter { Name = name, Value = value, Mode = ParameterMode.Raw });
            return a;
        }
        public static ParameterCollection AddRaw(this ParameterCollection a, string name, object value)
        {
            a.Add(new Parameter { Name = name, Value = JSON.Serialize(value), Mode = ParameterMode.Raw });
            return a;
        }

        #endregion



        public static int GetLabelWidthAndPad(this AbstractContainer cmp, int defaultLabelWidthAndPad = 100 + 5)
        {
            var frm = cmp as Ext.Net.FormPanelBase;
            if (frm != null && frm.FieldDefaults.LabelWidth > 0)
                return frm.FieldDefaults.LabelWidth + frm.FieldDefaults.LabelPad;

            var fc = cmp as Ext.Net.FieldContainerBase;
            if (fc != null && fc.FieldDefaults.LabelWidth > 0)
                return fc.FieldDefaults.LabelWidth + fc.FieldDefaults.LabelPad;

            var formLayout = cmp.LayoutConfig.Primary as FormLayoutConfig;
            if (formLayout != null)
            {
                ConfigOption labelWidthCfg;
                if (formLayout.ConfigOptions.TryGetValue("labelWidth", out labelWidthCfg))
                {
                    var labelPad = 5;
                    ConfigOption labelPadCfg;
                    if (formLayout.ConfigOptions.TryGetValue("labelPad", out labelPadCfg))
                        labelPad = labelPadCfg.Value.ToInt();
                    return labelWidthCfg.Value.ToInt() + labelPad;
                }
            }

            return defaultLabelWidthAndPad;
        }


    }
}

